<template>
	<div class="block-main2" v-if="isMobile">

		<!-- 移动端使用摄像头扫码 -->
		<div class="qr-container">
			<div class="scan-box">
				<!-- <qrcode-stream :key="qrStreamKey" @detect="onDecode" @error="onError" :torch="torchActive"></qrcode-stream> -->
				<qrcode-stream :key="qrStreamKey" @detect="onDecode" @error="onError"></qrcode-stream>
				<div class="scan-line"></div>
				<div class="scan-angle scan-angle-lt"></div>
				<div class="scan-angle scan-angle-rt"></div>
				<div class="scan-angle scan-angle-lb"></div>
				<div class="scan-angle scan-angle-rb"></div>
				<!-- <div v-if="hasTorch" class="torch-button" @click="toggleTorch">
					<i class="torch-icon" :class="{ 'torch-active': torchActive }"></i>
				</div> -->
			</div>
		</div>

	</div>
	<div class="block-main" v-else>
		<!-- 电脑端使用文件上传 -->
		<div class="qr-container">
			<label class="custom-upload">
				选择二维码文件
				<input type="file" class="hidden-input" @change="handleFileUpload" accept="image/*">
			</label>
		</div>
		<!-- <div v-else class="qr-container">
			<qrcode-capture @detect="onDecode" :key="qrStreamKey"></qrcode-capture>
		</div> -->
	</div>
</template>
<script setup>
	import {
		ref,
		onMounted
	} from "vue";
	import {
		useRouter
	} from "vue-router";
	import {
		QrcodeStream,
		QrcodeCapture,
	} from "vue-qrcode-reader";
	import {
		showToast,
		showDialog
	} from "vant";
	import {
		checkEntity
	} from "@/api/deviceEntity";
	import jsQR from 'jsqr';
	import {
		getUserid
	} from '@/utils/auth';
	import '@/api/wx.js';
	import wx from 'weixin-jsapi';

	const isMobile = ref(false);
	const qrStreamKey = ref(0); // 添加key值用于强制重新渲染组件
	const hasCameraPermission = ref(false);

	const torchActive = ref(false);
	const hasTorch = ref(false);

	const toggleTorch = () => {
		torchActive.value = !torchActive.value;
	};

	onMounted(() => {
		isMobile.value = /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent);
		// 检查是否已有摄像头授权
		hasCameraPermission.value = localStorage.getItem('cameraPermission') === 'granted';

		// 如果已授权，尝试获取媒体设备
		if (hasCameraPermission.value) {
			navigator.mediaDevices.getUserMedia({ video: true })
				.catch(() => {
					// 如果获取失败，可能是用户在浏览器设置中撤销了权限
					hasCameraPermission.value = false;
					localStorage.removeItem('cameraPermission');
				});
		}
	});

	const router = useRouter();

	const params = ref({
		userId: getUserid(),
		deviceNumber: ''
	});
	//console.log(router.currentRoute.value.fullPath)
	// 扫码成功后的回调
	const onDecode = async (detectedCodes) => {
		// 用户允许访问摄像头时保存授权状态
		if (!hasCameraPermission.value) {
			hasCameraPermission.value = true;
			localStorage.setItem('cameraPermission', 'granted');
		}
		if (detectedCodes.length > 0) {
			try {
				const qrUrl = detectedCodes[0].rawValue
				const urlObj = new URL(qrUrl);
				const deviceNumber = urlObj.searchParams.get('deviceNumber');

				if (!deviceNumber) {
					showToast("二维码中未包含设备编号");
					// 更新key值，强制重新渲染组件
					qrStreamKey.value++;
					return;
				}

				params.value.deviceNumber = deviceNumber;

				const response = await checkEntity(params.value);
				if (response.status == 200) {
					router.replace({
						name: 'binding',
						params: {
							deviceNumber: deviceNumber
						}
					});
				} else {
					showToast({
						type: 'fail',
						message: response.desc || '未能识别二维码',
						forbidClick: true,
						duration: 1000
					});
					// 更新key值，强制重新渲染组件
					qrStreamKey.value++;
				}
			} catch (err) {
				//console.log('二维码解析错误:', err);
				showToast({
					type: 'fail',
					message: err.desc || '未能识别二维码',
					forbidClick: true,
					duration: 1000
				});
				// 更新key值，强制重新渲染组件
				qrStreamKey.value++;
			}
		} else {
			showToast("扫码失败");
			// 更新key值，强制重新渲染组件
			qrStreamKey.value++;
		}
	};

	const onCameraReady = (res) => {
		//console.log(res)
		//console.log("摄像头准备好了");
	};

	//错误提示
	const onError = (error) => {
		var message = '摄像头错误';
		if (error.name === "NotAllowedError") {
			message = '用户拒绝相机访问权限';
			// 清除授权状态
			hasCameraPermission.value = false;
			localStorage.removeItem('cameraPermission');
		} else if (error.name === "NotFoundError") {
			message = '未安装合适的摄像设备'
		} else if (error.name === "NotSupportedError") {
			message = '当前网页没有通过 HTTPS 或 localhost 安全协议提供服务'
		} else if (error.name === "NotReadableError") {
			message = '相机被占用了'
		} else if (error.name === "OverconstrainedError") {
			message = '尝试使用前置摄像头'
		} else if (error.name === "StreamApiNotSupportedError") {
			message = '浏览器似乎缺少功能'
		} else if (error.name === "InsecureContextError") {
			message = '当前网页没有通过 HTTPS 或 localhost 安全协议提供服务'
		} else {
			// 如果是其他错误，也清除授权状态
			hasCameraPermission.value = false;
			localStorage.removeItem('cameraPermission');
		}
		showDialog({
			title: '提示',
			message: message,
		}).then(() => {
			// 更新key值，强制重新渲染组件
			// qrStreamKey.value++;
		});
	};


	const wechatScan = () => {
		wx.scanQRCode({
			needResult: 1, 
			scanType: ["qrCode", "barCode"], 
			success: function (res) {
				try {
					const qrUrl = res.resultStr;
					const urlObj = new URL(qrUrl);
					const deviceNumber = urlObj.searchParams.get('deviceNumber');

					if (!deviceNumber) {
						showToast("二维码中未包含设备编号");
						return;
					}

					params.value.deviceNumber = deviceNumber;

					checkEntity(params.value).then(response => {
						if (response.status == 200) {
							router.replace({
								name: 'binding',
								params: {
									deviceNumber: deviceNumber
								}
							});
						} else {
							showToast({
								type: 'fail',
								message: response.desc || '未能识别二维码',
								forbidClick: true,
								duration: 1000
							});
						}
					});
				} catch (err) {
					showToast({
						type: 'fail',
						message: err.desc || '未能识别二维码',
						forbidClick: true,
						duration: 1000
					});
				}
			},
			error: function (err) {
				showToast({
					type: 'fail',
					message: '微信扫码失败: ' + err.errMsg,
					forbidClick: true,
					duration: 1000
				});
			}
		});
	};

	// 打开相册函数
	const openAlbum = () => {
		wx.chooseImage({
			count: 1, // 最多可以选择的图片张数，默认9
			sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有
			sourceType: ['album'], // 可以指定来源是相册，默认二者都有
			success: function (res) {
				const localIds = res.localIds; // 返回选定照片的本地ID列表，localId可以作为img标签的src属性显示图片
				wx.uploadImage({
					localId: localIds[0], // 需要上传的图片的本地ID，由chooseImage接口获得
					isShowProgressTips: 1, // 显示进度提示
					success: function (res) {
						const serverId = res.serverId; // 返回图片的服务器端ID
						// 这里需要调用后端接口，传入 serverId 下载图片并解析二维码
						// 假设这里有一个后端接口名为 decodeWechatImage
						// 你需要根据实际情况修改接口地址和请求方式
						fetch('/api/decodeWechatImage', {
							method: 'POST',
							headers: {
								'Content-Type': 'application/json'
							},
							body: JSON.stringify({ serverId })
						})
						.then(response => response.json())
						.then(data => {
							if (data.deviceNumber) {
								params.value.deviceNumber = data.deviceNumber;
								checkEntity(params.value).then(response => {
									if (response.status == 200) {
										router.replace({
											name: 'binding',
											params: {
												deviceNumber: data.deviceNumber
											}
										});
									} else {
										showToast({
											type: 'fail',
											message: response.desc || '未能识别二维码',
											forbidClick: true,
											duration: 1000
										});
									}
								});
							} else {
								showToast("二维码中未包含设备编号");
							}
						})
						.catch(err => {
							showToast({
								type: 'fail',
								message: '解析二维码失败: ' + err.message,
								forbidClick: true,
								duration: 1000
							});
						});
					},
					error: function (err) {
						showToast({
							type: 'fail',
							message: '上传图片失败: ' + err.errMsg,
							forbidClick: true,
							duration: 1000
						});
					}
				});
			},
			error: function (err) {
				showToast({
					type: 'fail',
					message: '打开相册失败: ' + err.errMsg,
					forbidClick: true,
					duration: 1000
				});
			}
		});
	};

	const handleFileUpload = async (event) => {
		const file = event.target.files[0];
		if (!file) return;

		const reader = new FileReader();
		reader.onload = (e) => {
			const img = new Image();
			img.src = e.target.result;
			img.onload = async () => {
				const canvas = document.createElement("canvas");
				const ctx = canvas.getContext("2d");
				canvas.width = img.width;
				canvas.height = img.height;
				ctx.drawImage(img, 0, 0, img.width, img.height);
				const imageData = ctx.getImageData(0, 0, img.width, img.height);
				const code = jsQR(imageData.data, imageData.width, imageData.height);
				if (code) {
					try {
						const qrUrl = code.data
						const urlObj = new URL(qrUrl);
						const deviceNumber = urlObj.searchParams.get('deviceNumber');

						if (!deviceNumber) {
							showToast("二维码中未包含设备编号");
							const input = event.target;
							// 解决相同文件不触发 onChange 的问题
							input.value = "";
							return;
						}

						params.value.deviceNumber = deviceNumber;

						const response = await checkEntity(params.value);
						if (response.status == 200) {
							router.replace({
								name: 'binding',
								params: {
									deviceNumber: deviceNumber
								}
							});
						} else {
							showToast({
								type: 'fail',
								message: response.desc || '未能识别二维码',
								forbidClick: true,
								duration: 1000
							});
						}
					} catch (err) {
						showToast({
							type: 'fail',
							message: err.desc || '未能识别二维码',
							forbidClick: true,
							duration: 1000
						});

					}
				} else {
					showToast("未能识别二维码");
				}
				const input = event.target;
				// 解决相同文件不触发 onChange 的问题
				input.value = "";
			};
		};
		reader.readAsDataURL(file);
	};
</script>
<style lang="scss" scoped>
	.block-main {
		height: 100%;
		background: #fff;
		overflow: hidden;
		font-size: 16px;
	}

	.block-main2{
		height: calc(100vh - 50px);
		overflow: hidden;
		font-size: 16px;
	}

	.qr-container {
		display: flex;
		justify-content: center;
		align-items: center;
		height: 100%;
	}

	.scan-overlay {
		background-color: rgba(0, 0, 0, 0.7);
	}

	.qr-container {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		height: 100%;
		color: #fff;
	}

	.scan-tips {
		margin-bottom: 20px;
		font-size: 16px;
	}

	.scan-desc {
		margin-top: 20px;
		font-size: 14px;
		color: rgba(255, 255, 255, 0.8);
	}

	.scan-box {
		position: relative;
		width: 100vw;
		height: 100%;
		background-color: transparent;
		overflow: hidden;

		:deep(.qrcode-stream) {
			width: 100%;
			height: 100%;
		}
	}

	.scan-line {
		position: absolute;
		left: 0;
		top: 0;
		width: 100%;
		height: 4px;
		background: linear-gradient(to right, transparent, #07c160, transparent);
		animation: scanMove 3s ease-in-out infinite;
	}

	.scan-angle {
		position: absolute;
		width: 28px;
		height: 28px;
		border-color: #07c160;
		border-style: solid;
		border-width: 4px;
	}

	.scan-angle-lt {
		left: 0;
		top: 0;
		border-right: none;
		border-bottom: none;
	}

	.scan-angle-rt {
		right: 0;
		top: 0;
		border-left: none;
		border-bottom: none;
	}

	.scan-angle-lb {
		left: 0;
		bottom: 0;
		border-right: none;
		border-top: none;
	}

	.scan-angle-rb {
		right: 0;
		bottom: 0;
		border-left: none;
		border-top: none;
	}

	@keyframes scanMove {
		0% {
			top: 0;
			opacity: 1;
		}
		50% {
			opacity: 0.8;
		}
		100% {
			top: 100%;
			opacity: 1;
		}
	}

	.custom-upload {
		display: inline-block;
		padding: 10px 20px;
		background-color: #1989fa;
		color: white;
		border-radius: 5px;
		cursor: pointer;
		font-size: 16px;
	}

	.hidden-input {
		display: none;
	}

	.torch-button {
		position: absolute;
		bottom: 20px;
		right: 20px;
		width: 40px;
		height: 40px;
		border-radius: 50%;
		background-color: rgba(0, 0, 0, 0.5);
		display: flex;
		justify-content: center;
		align-items: center;
		cursor: pointer;
	}

	.torch-icon {
		width: 24px;
		height: 24px;
		background: url('') center/contain no-repeat;
	}

	.torch-icon.torch-active {
		background: url('') center/contain no-repeat;
	}
</style>
